#define CURL_STATICLIB
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <curl/curl.h>
extern char _binary_KeyList_start;
extern char _binary_KeyList_end;
extern char _binary_HelpList_start;
extern char _binary_HelpList_end;


struct string {
    char *ptr;
    size_t len;
};

void init_string(struct string *s) {
    s->len = 0;
    s->ptr = malloc(s->len+1);
    if (s->ptr == NULL) {
        fprintf(stderr, "malloc() failed\n");
        exit(EXIT_FAILURE);
    }
    s->ptr[0] = '\0';
}

size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s)
{
    size_t new_len = s->len + size*nmemb;
    s->ptr = realloc(s->ptr, new_len+1);
    if (s->ptr == NULL) {
        fprintf(stderr, "realloc() failed\n");
        exit(EXIT_FAILURE);
    }
    memcpy(s->ptr+s->len, ptr, size*nmemb);
    s->ptr[new_len] = '\0';
    s->len = new_len;

    return size*nmemb;
}


int main(int argc, char* argv[]) {
    char* argument1 = argv[1];
    char* argument2 = argv[2];
    char place[3]; //qfix
    snprintf(place, sizeof(place), "-h");

    if(argc < 2)
    {
        ShowHelp();
        return 0;
    }

    if (strstr(argv[1], "-update") != NULL) {
        UpdateXbmc();
        return 0;
    }

    if (strstr(argv[1], "-clean") != NULL) {
        CleanXbmc();
        return 0;
    }



    if (strstr(argv[1], "-k") != NULL) {
        ShowKeys();
        return 0;
    }

    if(argc >2) {
        postIEA(argument1,argument2);
    }
    else {
        postIEA(place,argument1);
    }
}

int postIEA(char moreopt[], char* command[]) {
    char json[1024];
    snprintf(json, sizeof(json), "{ \"jsonrpc\": \"2.0\", \"method\": \"Input.ExecuteAction\", \"params\": { \"action\": \"%s\" }, \"id\": \"1\" }", command);
    CURLcode res;
    CURL *curl = curl_easy_init();
    {
        struct string s;
        init_string(&s);
        struct curl_slist *headers=NULL;
        headers = curl_slist_append(headers, "content-Type: application/json");
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json);
        curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.14/jsonrpc");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
        res = curl_easy_perform(curl);
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);

        if (strstr(moreopt, "-v") != NULL) {
            printVERBOSE(command,s.ptr);
            free(s.ptr);
        }
        else {
            free(s.ptr);
            return 0;
        }
    }
}
int printVERBOSE(char* command[], char* result[]) {
    char resultC[512];
    snprintf(resultC, sizeof resultC, "%s", result);
    if (strstr(resultC, "OK") != NULL) {
        printf("%s - OK\n",command);
        return 0;
    }
    else {
        printf("%s - FAILED\n",command);
        return 1;
    }

    return 0;
}


int ShowKeys() {
    char*  p = &_binary_KeyList_start;
    while ( p != &_binary_KeyList_end ) putchar(*p++);
}

int ShowHelp() {
    char*  p = &_binary_HelpList_start;
    while ( p != &_binary_HelpList_end ) putchar(*p++);
}

UpdateXbmc() {
    char Result[512];
    char Update[512];
    snprintf(Update, sizeof(Update),"{ \"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.Scan\", \"id\": \"mybash\"}");
    CURLcode res;
    CURL *curl = curl_easy_init();
    {
        struct string s;
        init_string(&s);
        struct curl_slist *headers=NULL;
        headers = curl_slist_append(headers, "content-Type: application/json");
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, Update);
        curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.14/jsonrpc");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
        res = curl_easy_perform(curl);
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);


        snprintf(Result, sizeof Result, "%s", s.ptr);
        if (strstr(Result, "OK") != NULL) {
            printf("Update - OK\n");
            return 0;
            free(s.ptr);
        }
        else {
            printf("Update - FAILED\n");
            return 0;
            free(s.ptr);
        }
    }
    return 0;
}


CleanXbmc() {
    char Result[512];
    char Update[512];
    snprintf(Update, sizeof(Update),"{ \"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.Clean\", \"id\": \"mybash\"}");
    CURLcode res;
    CURL *curl = curl_easy_init();
    {
        struct string s;
        init_string(&s);
        struct curl_slist *headers=NULL;
        headers = curl_slist_append(headers, "content-Type: application/json");
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, Update);
        curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.14/jsonrpc");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
        res = curl_easy_perform(curl);
        curl_slist_free_all(headers);
        curl_easy_cleanup(curl);


        snprintf(Result, sizeof Result, "%s", s.ptr);
        if (strstr(Result, "OK") != NULL) {
            printf("Clean - OK\n");
            return 0;
            free(s.ptr);
        }
        else {
            printf("Clean - FAILED\n");
            return 0;
            free(s.ptr);
        }

    }
    return 0;
}

